package com.isyscore.os.metadata.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.isyscore.device.common.model.RespDTO;
import com.isyscore.os.metadata.model.dto.*;
import com.isyscore.os.metadata.model.dto.req.ChangeMetricGroupReq;
import com.isyscore.os.metadata.model.dto.req.ChangeMetricNameReq;
import com.isyscore.os.metadata.model.dto.req.MetricCreateUpdateReq;
import com.isyscore.os.metadata.model.dto.req.MetricPageQuery;
import com.isyscore.os.metadata.model.entity.Metric;
import com.isyscore.os.metadata.service.impl.MetricGraphService;
import com.isyscore.os.metadata.service.impl.MetricService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

import static com.isyscore.os.metadata.constant.CommonConstant.DEFAULT_METRIC_GROUP_ID;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author wany
 * @since 2021-08-11
 */
@RestController
@RequestMapping("${api-full-prefix}/metric")
@Api(tags = "数据指标")
public class MetricController {

    @Autowired
    private MetricService metricService;

    @Autowired
    private MetricGraphService metricGraphService;

    @ApiOperation("分页查询数据指标列表")
    @GetMapping("/page")
    public RespDTO<IPage<MetricListDTO>> pageMetric(MetricPageQuery pageQuery) {
        IPage<Metric> metrics = metricService.pageWithPageParam(pageQuery);
        IPage<MetricListDTO> pageData = metrics.convert((metric) -> {
            MetricListDTO listDto = new MetricListDTO();
            listDto.setId(metric.getId());
            listDto.setName(metric.getName());
            listDto.setGroupId(metric.getGroupRefId());
            listDto.setDescription(metric.getDescription());
            listDto.setCreateTime(metric.getCreateTime());
            return listDto;
        });
        return RespDTO.onSuc(pageData);
    }

    @ApiOperation("查看数据指标详情")
    @GetMapping("/{metricId}")
    public RespDTO<MetricDTO> getMetricDetail(@PathVariable("metricId") Long metricId) {
        MetricDTO detail = metricService.getMetricDetailById(metricId);
        return RespDTO.onSuc(detail);
    }

    @ApiOperation("创建新的数据指标")
    @PostMapping()
    public RespDTO<Long> addMetric(@Validated @RequestBody MetricCreateUpdateReq metricCreateUpdateReq) {
        Metric metric = metricService.createMetric(metricCreateUpdateReq);
        return RespDTO.onSuc(metric.getId());
    }

    @ApiOperation("修改指定的数据指标")
    @PutMapping("/{metricId}")
    public RespDTO<?> updateMetric(@PathVariable("metricId") Long metricId, @Validated @RequestBody MetricCreateUpdateReq metricCreateUpdateReq) {
        metricService.updateMetric(metricId, metricCreateUpdateReq);
        return RespDTO.onSuc();
    }

    @ApiOperation("删除指定的指标，如果当前指标被其它派生指标则无法删除")
    @DeleteMapping("/{metricId}")
    public RespDTO<?> deleteMetric(@PathVariable("metricId") Long metricId) {
        metricService.deleteMetric(metricId);
        return RespDTO.onSuc();
    }

    @ApiOperation("查询数据指标的血缘关系")
    @GetMapping("/graph/{metricId}")
    public RespDTO<MetricGraphDTO> getMetricGraph(@PathVariable("metricId") Long metricId) {
        MetricGraphDTO graph = metricGraphService.getMetricGrath(metricId);
        return RespDTO.onSuc(graph);
    }

    @ApiOperation("获取特定指标的时间范围选项")
    @GetMapping("/period/{metricId}")
    public RespDTO<List<String>> getMetricPeriodsByCode(@PathVariable("metricId") Long metricId, @RequestParam("numberOfPeriods") Integer numberOfPeriods) {
        List<TimePeriodDTO> timeperiods = metricService.getPeriodsByMetric(metricId, numberOfPeriods);
        return RespDTO.onSuc(timeperiods.stream().map(TimePeriodDTO::getKey).collect(Collectors.toList()));
    }

    @ApiOperation("指标定时计算任务的结果查询")
    @GetMapping("/results/{metricId}")
    public RespDTO<List<MetricResultDTO>> getMetricResults(@PathVariable("metricId") Long metricId,
                                                           @RequestParam(value = "timePeriod", required = false) String timePeriod,
                                                           @RequestParam(value = "dimOrder", required = false) String dimOrder,
                                                           @RequestParam(value = "dimension", required = false) String dimension) {
        List<MetricResultDTO> resultObj = metricService.queryMetricJobResultByPeriod(metricId, timePeriod, dimOrder, dimension);
        return RespDTO.onSuc(resultObj);
    }

    @ApiOperation("(内部API)获取指标及其分组信息的树形结构,可根据指标名称进行搜索")
    @GetMapping("/tree")
    public RespDTO<List<MetricTreeItemDTO>> getMetricByName(@RequestParam(value = "name", required = false) String name) {
        return RespDTO.onSuc(metricService.getMetricAndGroupWithTree(name));
    }

    @ApiOperation("(内部API)修改指标的分组")
    @PutMapping("/changeGroup")
    public RespDTO<?> groupChange(@Validated @RequestBody ChangeMetricGroupReq changeMetricGroupReq) {
        Metric metric = metricService.getMetricById(changeMetricGroupReq.getMetricId());
        if (changeMetricGroupReq.getGroupId() == null) {
            metric.setGroupRefId(DEFAULT_METRIC_GROUP_ID);
        } else {
            metric.setGroupRefId(changeMetricGroupReq.getGroupId());
        }
        metricService.updateById(metric);
        return RespDTO.onSuc();
    }

    @ApiOperation("(内部API)指标重命名")
    @PutMapping("/rename")
    public RespDTO<?> renameMetric(@Validated @RequestBody ChangeMetricNameReq changeMetricNameReq) {
        Metric metric = metricService.getMetricById(changeMetricNameReq.getMetricId());
        metric.setName(changeMetricNameReq.getNewName());
        metricService.updateById(metric);
        return RespDTO.onSuc();
    }


}